import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import re
from matplotlib.ticker import MultipleLocator

# 设置全局配置
font_size = 16
dpi = 100
linewidth = 2
params = {'axes.titlesize': font_size,
          'legend.fontsize': font_size,
          'figure.dpi': dpi,
          'figure.figsize': (8, 6),
          'axes.labelsize': font_size,
          'xtick.labelsize': font_size,
          'ytick.labelsize': font_size,
          'figure.titlesize': font_size}
plt.rcParams.update(params)
plt.rcParams["font.sans-serif"] = ["Times New Roman"]  # 设置字体
plt.rcParams["axes.unicode_minus"] = False  # 该语句解决图像中的“-”负号的乱码问题
# plt.style.use('seaborn-whitegrid')
sns.set_style("white")


# 根据输入的两个loss列表画出曲线图
def plot_loss_curves(loss_list: np.ndarray,
                     titles: list = None,
                     xlabel: list = None,
                     ylabel: list = None,
                     labels: list = None,
                     colors: list = None,
                     batch_num=1,
                     spacing=3,
                     col_num=3):
    if len(loss_list.shape) < 3:
        raise ValueError('the shape of loss_list should be of 3')
    shape = loss_list.shape
    if not colors:
        colors = np.random.rand(shape[1], 3)
    if not labels:
        labels = [f'Loss {i}' for i in range(1, shape[1] + 1)]
    if not titles:
        titles = [f'model {i}' for i in range(1, shape[0] + 1)]
    if not xlabel:
        xlabel = ['epochs'] * shape[0]
    if not ylabel:
        ylabel = ['loss'] * shape[0]

    major_locator = MultipleLocator(spacing)
    epochs = shape[-1] // batch_num
    x = np.linspace(1, epochs, shape[-1])
    # 创建一个新的Figure对象
    fig = plt.figure()
    # 创建一个Axes对象
    for i in range(shape[0]):
        ax = fig.add_subplot(int(np.ceil(shape[0] / col_num)), col_num, i + 1)
        for index, loss in enumerate(loss_list[i]):
            ax.plot(x, loss, linewidth=linewidth, color=colors[index], label=labels[index])
        ax.set_title(titles[i])
        ax.set_xlabel(xlabel[i])
        ax.set_ylabel(ylabel[i])
        ax.xaxis.set_major_locator(major_locator)
        ax.legend()

    # plt.xlim(0.3, epochs + 0.5)
    plt.show()


def write_data(path, loss):
    df = pd.DataFrame(loss, columns=['loss'])
    writer = pd.ExcelWriter(path)
    df.to_excel(writer, index=False)
    writer.save()
    print('save successfully!')


def read_data(paths: list):
    size = len(paths)
    data = np.asarray(pd.read_excel(paths[0])).flatten()
    length = len(data)
    res = np.zeros(shape=(size, length))
    res[0] = np.asarray(data)
    for index, path in enumerate(paths[1:]):
        res[index + 1] = np.asarray(pd.read_excel(path)).flatten()
    return res


def plot_confusion_matrix(cm, classes, title='Confusion Matrix'):
    plt.figure(figsize=(9, 8), dpi=100)
    np.set_printoptions(precision=2)

    # 在混淆矩阵中每格的概率值
    ind_array = np.arange(len(classes))
    x, y = np.meshgrid(ind_array, ind_array)
    for x_val, y_val in zip(x.flatten(), y.flatten()):
        c = cm[y_val][x_val]
        if c > 0.001:
            plt.text(x_val, y_val, "%d" % (c,), color='red', va='center', ha='center')

    plt.imshow(cm, interpolation='nearest', cmap=plt.cm.binary)
    plt.title(title)
    plt.colorbar()
    xlocations = np.array(range(len(classes)))
    plt.xticks(xlocations, classes, rotation=90)
    plt.yticks(xlocations, classes)
    plt.ylabel('Actual label')
    plt.xlabel('Predict label')

    # offset the tick
    tick_marks = np.array(range(len(classes))) + 0.5
    plt.gca().set_xticks(tick_marks, minor=True)
    plt.gca().set_yticks(tick_marks, minor=True)
    plt.gca().xaxis.set_ticks_position('none')
    plt.gca().yaxis.set_ticks_position('none')
    plt.grid(True, which='minor', linestyle='-')
    plt.gcf().subplots_adjust(bottom=0.15)
    plt.tight_layout()

    # show confusion matrix
    # plt.savefig(savename, format='png')
    plt.show()


# if __name__ == '__main__':



    #
    # # loss = read_data([r'E:\desktop\毕业论文\xww\train_loss.xlsx',
    # #                   r'E:\desktop\毕业论文\xww\test_loss.xlsx'])
    # # loss = loss[None, ...]
    # # plot_loss_curves(loss, spacing=5, col_num=1, colors=['blue', 'red'], labels=['train loss', 'test loss'])
    # news_data = pd.read_csv('./data/news_data/news.dat', delimiter='::', header=None,
    #                         names=['news_id', 'title', 'category'],engine='python')
    # rate_data = pd.read_csv('./data/news_data/ratings.dat', delimiter='::', header=None,
    #                         names=['user_id', 'news_id', 'rating', 'time'],engine='python')
    # user_data = np.arange(1, 6041)
    # news = []
    # for each in user_data:
    #     temp = rate_data[rate_data['user_id']==each][['rating','news_id','']]
    #     print(temp)
    #     break
    #     # cate = news_data[news_data['']][]
    # # cm = np.asarray([[]])

    # x = ['True', 'False']
    # y = [5289, 751]
    #
    # plt.bar(x, y, color=['#1f77b4', '#ff7f0e'], width=0.6)
    # plt.title('Distribution of Data')
    # plt.xlabel('Data Values')
    # plt.ylabel('Count')
    # # plt.xticks(fontsize=12)
    # # plt.yticks(fontsize=12)
    # plt.grid(axis='y', alpha=0.5)
    #
    # # 在每个柱子上方添加 y 值文本
    # for i, v in enumerate(y):
    #     plt.text(i, v + 50, str(v), ha='center', fontweight='bold',fontsize=16)
    #
    # plt.show()

